function [ frames, frm_bypass ] = framing( data, header, framesize, increment )
%FRAME Summary of this function goes here
%   Detailed explanation goes here

if ~exist('framesize', 'var') || isempty(framesize)
    framesize = [0.25 2 2];
end
if ~exist('increment', 'var') || isempty(increment)
    increment = [0.25 1.2 1.2];
end

corr_size = 1.5;

% check sample_rate consistency
sample_rate = header{1}.sample_rate;
for h = header
    if h{1}.sample_rate ~= sample_rate
        printf('Sample rate not consistent. Exiting.');
        return
    end
end

% initialize variables
min_fsize = framesize(1) * sample_rate;
cur_fsize = framesize(2) * sample_rate;
max_fsize = framesize(3) * sample_rate;
corr_size = corr_size * sample_rate;
min_inc = increment(1) * sample_rate;
cur_inc = increment(2) * sample_rate;
max_inc = increment(3) * sample_rate;

frm_start = [];
frm_end = [];
frm_bypass = [];
cur_pos = 1;
%cmax_last = 0;
%cmin_last = 0;

frm_start(end+1) = cur_pos;
frm_end(end+1) = cur_pos + cur_fsize - 1;
frm_bypass(end+1) = 0;
tok = 0;

while cur_pos + corr_size + max_fsize < size(data, 1)
    % find the best correlation
    lframe = data(cur_pos+(1:corr_size), 2:end);
    lframe_mean = sum(lframe, 1);
    ascale = max(lframe, [], 1) - min(lframe, [], 1);
    cscale = sum(lframe .* lframe, 1) .* corr_size - lframe_mean .* lframe_mean;
    cmin = 0;
    cmax = 0; cmax_i = 0;
    csum = 0;
    carray = zeros(max_fsize - min_fsize + 1, 1);
    for i = min_fsize:max_fsize
        bypass = 0;
        nframe = data(cur_pos+i+(1:corr_size), 2:end);
        nframe_mean = sum(nframe, 1);
        cscale2 = sum(nframe .* nframe, 1) .* corr_size - nframe_mean .* nframe_mean;
        c = sum(lframe .* nframe, 1) .* corr_size;
        c = c - lframe_mean .* nframe_mean;
        c = c ./ sqrt(cscale .* cscale2);
        c(isnan(c))=0;
        c = sum(c);
        csum = csum + c;
        carray(i - min_fsize +1) = c;
        if cmin ==0 || c < cmin; cmin = c; end
        if cmax ==0 || c > cmax; cmax = c; cmax_i = i; end
        %if cmax_last == 0 || cmin_last == 0; continue; end
        %if i > cur_fsize * 1.1 && (c-cmin)/(cmax-cmin) < 0.1 && (cmax/cmin*cmin_last-cmin_last)/(cmax_last-cmin_last) > 0.8
        if i > cur_fsize * 1.1 && (c-cmin)/(cmax-cmin) < 0.5 && (csum / (i-min_fsize+1) - cmin) / (cmax-cmin) < 0.4
            bypass = 1;
            break;
        end
    end
    %cmax_last = cmax; cmin_last = cmin;
    
    if cmax > 0  % this is really a positive correlation
        % now do peak finding
        if ~bypass
            thres = 0.9 * (cmax - cmin) + cmin;
            i = (carray > thres);
            i = diff(i);
            lb = find(i == 1, 1);
            if isempty(lb); lb = 1; end;
            rb = find(i(lb:end) == -1, 1) + lb - 1;
            if isempty(rb); rb = length(i); end;
            [cmax cmax_i] = max(carray(lb:rb));
            cmax_i = cmax_i + lb + min_fsize -2;
        end
        % find best starting position
        tmp_max_inc = min(max_inc, cmax_i);
        %ascale = ascale .* [0 0 0 0 0 0 1 1 1];
        %aarray = data(cur_pos + (min_inc:max_inc), 2:end) + data(cur_pos + cmax_i + (min_inc:max_inc), 2:end);
        %aarray = sum(aarray ./ (ones(max_inc-min_inc+1,1) * ascale), 2);
        %aarray = min(data(cur_pos + (min_inc:max_inc), 2:end), [], 2) + min(data(cur_pos + cmax_i + (min_inc:max_inc), 2:end), [], 2);
        %aarray = abs(data(cur_pos + (min_inc:tmp_max_inc), 6)); % + data(cur_pos + cmax_i + (min_inc:tmp_max_inc), 6);
        %[dummy inc] = min(aarray);
        %cur_inc = inc + min_inc - 1;
        cur_inc = cmax_i;
        
        cur_pos = cur_pos + cur_inc;
        cur_fsize = cmax_i;
    else
        cur_pos = cur_pos + cur_inc;
    end
    
    if cur_pos + cur_fsize -1 > frm_end(end) 
        frm_start(end+1) = cur_pos;
        frm_end(end+1) = cur_pos + cur_fsize - 1;
        frm_bypass(end+1) = bypass;
    end
    
    tok = tok + 1;
    if mod(tok, 50) == 0
        disp(['Framing - ' num2str(round(cur_pos/size(data,1)*100)) '%']);
    end
end

frames = [frm_start; frm_end];
disp(['Framing - 100%']);

end

